#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include "../inc/s_modbus_rtu.h"

// 全局从站上下文
static modbus_slave_ctx_t g_slave_ctx;

/**
 * @brief 工具函数：去除字符串首尾空格
 */
static char *str_trim(char *str) {
    if (!str) return NULL;
    while (isspace((unsigned char)*str)) str++;
    if (*str == '\0') return str;
    char *end = str + strlen(str) - 1;
    while (end > str && isspace((unsigned char)*end)) end--;
    end[1] = '\0';
    return str;
}

/**
 * @brief 解析 INI 格式设备模板文件
 */
int modbus_template_parse(modbus_device_template_t *template) {
    if (!template) return -1;
    memset(template, 0, sizeof(modbus_device_template_t));

    FILE *fp = fopen(TEMPLATE_FILE, "r");
    if (!fp) {
        printf("Slave: Open template file failed: %s\n", TEMPLATE_FILE);
        return -1;
    }

    char line[256] = {0};
    char current_section[MAX_SECTION_LEN] = {0};
    int is_target_device = 0;

    // 第一步：读取 DEVICE 字段，确定目标设备型号
    while (fgets(line, sizeof(line), fp)) {
        str_trim(line);
        if (line[0] == ';' || line[0] == '\0') continue;

        if (strncmp(line, "DEVICE", 6) == 0) {
            char *eq = strchr(line, '=');
            if (eq) {
                strncpy(template->dev_model, str_trim(eq + 1), sizeof(template->dev_model) - 1);
                printf("Slave: Target device model: %s\n", template->dev_model);
                break;
            }
        }
    }

    // 第二步：解析目标设备配置
    fseek(fp, 0, SEEK_SET);
    while (fgets(line, sizeof(line), fp)) {
        str_trim(line);
        if (line[0] == ';' || line[0] == '\0') continue;

        // 解析段名 [设备型号]
        if (line[0] == '[' && line[strlen(line)-1] == ']') {
            memset(current_section, 0, sizeof(current_section));
            strncpy(current_section, line + 1, strlen(line) - 2);
            str_trim(current_section);
            is_target_device = (strcmp(current_section, template->dev_model) == 0) ? 1 : 0;
            continue;
        }

        if (!is_target_device) continue;

        // 解析键值对 key=value
        char *eq = strchr(line, '=');
        if (!eq) continue;
        char key[MAX_KEY_LEN] = {0};
        char value[MAX_VALUE_LEN] = {0};
        strncpy(key, str_trim(line), eq - line);
        strncpy(value, str_trim(eq + 1), sizeof(value) - 1);

        // 解析通信参数
        if (strcmp(key, "SERIAL_DEV") == 0) {
            strncpy(template->comm_param.serial_dev, value, sizeof(template->comm_param.serial_dev) - 1);
        } else if (strcmp(key, "BAUDRATE") == 0) {
            template->comm_param.baudrate = atoi(value);
        } else if (strcmp(key, "PARITY") == 0) {
            template->comm_param.parity = (strcmp(value, "ODD") == 0) ? MODBUS_PARITY_ODD :
                                          (strcmp(value, "EVEN") == 0) ? MODBUS_PARITY_EVEN : MODBUS_PARITY_NONE;
        } else if (strcmp(key, "DATA_BITS") == 0) {
            template->comm_param.data_bits = atoi(value);
        } else if (strcmp(key, "STOP_BITS") == 0) {
            template->comm_param.stop_bits = atoi(value);
        } else if (strcmp(key, "DEFAULT_ADDR") == 0) {
            template->comm_param.default_addr = atoi(value);
        } else if (strcmp(key, "ADDR_REG") == 0) {
            template->comm_param.addr_reg = strtol(value, NULL, 16);
        }

            // 解析数据区配置
        else if (strcmp(key, "COIL_START") == 0) {
            template->data_config.coil_start = strtol(value, NULL, 16);
        } else if (strcmp(key, "COIL_CNT") == 0) {
            template->data_config.coil_cnt = atoi(value);
        } else if (strcmp(key, "DISCRETE_INPUT_START") == 0) {
            template->data_config.discrete_input_start = strtol(value, NULL, 16);
        } else if (strcmp(key, "DISCRETE_INPUT_CNT") == 0) {
            template->data_config.discrete_input_cnt = atoi(value);
        } else if (strcmp(key, "HOLD_REG_START") == 0) {
            template->data_config.hold_reg_start = strtol(value, NULL, 16);
        } else if (strcmp(key, "HOLD_REG_CNT") == 0) {
            template->data_config.hold_reg_cnt = atoi(value);
        } else if (strcmp(key, "INPUT_REG_START") == 0) {
            template->data_config.input_reg_start = strtol(value, NULL, 16);
        } else if (strcmp(key, "INPUT_REG_CNT") == 0) {
            template->data_config.input_reg_cnt = atoi(value);
        }

            // 解析保持寄存器初始值
        else if (strcmp(key, "HOLD_REG_INIT") == 0) {
            char *item = strtok(value, ",");
            while (item && template->hold_reg_init_cnt < MAX_REG_INIT_CNT) {
                str_trim(item);
                char *val_eq = strchr(item, '=');
                if (val_eq) {
                    modbus_reg_init_t *init = &template->hold_reg_init[template->hold_reg_init_cnt];
                    init->addr = strtol(str_trim(item), NULL, 16);
                    init->value = strtol(str_trim(val_eq + 1), NULL, 16);
                    template->hold_reg_init_cnt++;
                }
                item = strtok(NULL, ",");
            }
        }
    }

    fclose(fp);

    // 校验默认配置
    if (template->comm_param.baudrate == 0) template->comm_param.baudrate = 9600;
    if (template->comm_param.data_bits == 0) template->comm_param.data_bits = 8;
    if (template->comm_param.stop_bits == 0) template->comm_param.stop_bits = 1;
    if (template->comm_param.default_addr == 0) template->comm_param.default_addr = 248;
    if (template->comm_param.addr_reg == 0) template->comm_param.addr_reg = 0x0001;

    printf("Slave: Template parse success. Comm: %s, %d, %d,%d,%d\n",
           template->comm_param.serial_dev, template->comm_param.baudrate,
           template->comm_param.data_bits, template->comm_param.stop_bits, template->comm_param.parity);
    return 0;
}

/**
 * @brief 串口配置（基于模板通信参数）
 */
static int rtu_serial_config(modbus_comm_param_t *comm_param) {
    if (!comm_param) return -1;

    int fd = open(comm_param->serial_dev, O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd < 0) {
        printf("Slave: Serial open failed: %s\n", comm_param->serial_dev);
        return -1;
    }

    struct termios opt;
    tcgetattr(fd, &opt);

    // 设置波特率
    speed_t baud;
    switch (comm_param->baudrate) {
        case 19200: baud = B19200; break;
        case 38400: baud = B38400; break;
        case 115200: baud = B115200; break;
        default: baud = B9600; break;
    }
    cfsetispeed(&opt, baud);
    cfsetospeed(&opt, baud);

    // 配置数据位、校验位、停止位
    opt.c_cflag &= ~CSIZE;
    opt.c_cflag |= (comm_param->data_bits == 7) ? CS7 : CS8;

    if (comm_param->parity == MODBUS_PARITY_ODD) {
        opt.c_cflag |= PARENB | PARODD;
    } else if (comm_param->parity == MODBUS_PARITY_EVEN) {
        opt.c_cflag |= PARENB;
        opt.c_cflag &= ~PARODD;
    } else {
        opt.c_cflag &= ~PARENB;
    }

    opt.c_cflag = (comm_param->stop_bits == 2) ? (opt.c_cflag | CSTOPB) : (opt.c_cflag & ~CSTOPB);

    // 禁用硬件流控、原始模式
    opt.c_cflag &= ~CRTSCTS;
    opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    opt.c_oflag &= ~OPOST;
    opt.c_cc[VMIN] = 0;
    opt.c_cc[VTIME] = 1;
    tcflush(fd, TCIFLUSH);

    if (tcsetattr(fd, TCSANOW, &opt) != 0) {
        printf("Slave: Serial config failed\n");
        close(fd);
        return -1;
    }

    return fd;
}

/**
 * @brief 初始化数据区（含温湿度统计数据）
 */
static int modbus_slave_init_data(modbus_device_template_t *template) {
    modbus_data_config_t *data_cfg = &template->data_config;

    // 分配数据区内存
    if (data_cfg->coil_cnt > 0) {
        g_slave_ctx.coils = (uint8_t *)malloc(data_cfg->coil_cnt);
        memset(g_slave_ctx.coils, 0, data_cfg->coil_cnt);
    }
    if (data_cfg->discrete_input_cnt > 0) {
        g_slave_ctx.discrete_inputs = (uint8_t *)malloc(data_cfg->discrete_input_cnt);
        memset(g_slave_ctx.discrete_inputs, 0, data_cfg->discrete_input_cnt);
        g_slave_ctx.discrete_inputs[0] = 1; // 初始化为在线状态
    }
    if (data_cfg->hold_reg_cnt > 0) {
        g_slave_ctx.hold_regs = (uint16_t *)malloc(data_cfg->hold_reg_cnt * sizeof(uint16_t));
        memset(g_slave_ctx.hold_regs, 0, data_cfg->hold_reg_cnt * sizeof(uint16_t));
    }
    if (data_cfg->input_reg_cnt > 0) {
        g_slave_ctx.input_regs = (uint16_t *)malloc(data_cfg->input_reg_cnt * sizeof(uint16_t));
        memset(g_slave_ctx.input_regs, 0, data_cfg->input_reg_cnt * sizeof(uint16_t));
    }

    // 初始化保持寄存器初始值
    pthread_mutex_lock(&g_slave_ctx.data_mutex);
    for (uint16_t i = 0; i < template->hold_reg_init_cnt; i++) {
        modbus_reg_init_t *init = &template->hold_reg_init[i];
        if (init->addr >= data_cfg->hold_reg_start &&
            init->addr < data_cfg->hold_reg_start + data_cfg->hold_reg_cnt) {
            uint16_t idx = init->addr - data_cfg->hold_reg_start;
            g_slave_ctx.hold_regs[idx] = init->value;
        }
    }
    // 地址寄存器赋值（当前地址）
    uint16_t addr_reg_idx = template->comm_param.addr_reg - data_cfg->hold_reg_start;
    g_slave_ctx.hold_regs[addr_reg_idx] = g_slave_ctx.current_addr;

    // 初始化温湿度统计数据
    memset(g_slave_ctx.temp_history, 0, sizeof(g_slave_ctx.temp_history));
    memset(g_slave_ctx.humi_history, 0, sizeof(g_slave_ctx.humi_history));
    g_slave_ctx.history_idx = 0;
    g_slave_ctx.sample_cnt = 0;
    g_slave_ctx.temp_max = -400; // -40.0℃
    g_slave_ctx.temp_min = 1250; // 125.0℃
    g_slave_ctx.humi_max = 0;
    g_slave_ctx.humi_min = 1000; // 100.0%RH
    pthread_mutex_unlock(&g_slave_ctx.data_mutex);

    printf("Slave: Data init success. Current addr=%d\n", g_slave_ctx.current_addr);
    return 0;
}

/**
 * @brief 温湿度数据采样与统计（模拟传感器数据，实际替换为硬件读取）
 */
static void temp_humi_sample(void) {
    pthread_mutex_lock(&g_slave_ctx.data_mutex);

    // 模拟温湿度数据（0.1℃/0.1%RH 精度）
    int16_t temp = 250 + rand() % 50; // 25.0~30.0℃
    int16_t humi = 400 + rand() % 200; // 40.0~60.0%RH

    // 更新采样历史与统计
    g_slave_ctx.temp_history[g_slave_ctx.history_idx] = temp;
    g_slave_ctx.humi_history[g_slave_ctx.history_idx] = humi;
    g_slave_ctx.history_idx = (g_slave_ctx.history_idx + 1) % 10;
    g_slave_ctx.sample_cnt++;

    // 计算平均值
    int32_t temp_avg = 0, humi_avg = 0;
    for (int i = 0; i < 10; i++) {
        temp_avg += g_slave_ctx.temp_history[i];
        humi_avg += g_slave_ctx.humi_history[i];
    }
    temp_avg /= 10;
    humi_avg /= 10;

    // 更新最值
    if (temp > g_slave_ctx.temp_max) g_slave_ctx.temp_max = temp;
    if (temp < g_slave_ctx.temp_min) g_slave_ctx.temp_min = temp;
    if (humi > g_slave_ctx.humi_max) g_slave_ctx.humi_max = humi;
    if (humi < g_slave_ctx.humi_min) g_slave_ctx.humi_min = humi;

    // 更新输入寄存器（对应模板映射）
    g_slave_ctx.input_regs[0] = temp;                // 当前温度
    g_slave_ctx.input_regs[1] = humi;                // 当前湿度
    g_slave_ctx.input_regs[2] = temp_avg;            // 温度平均值
    g_slave_ctx.input_regs[3] = humi_avg;            // 湿度平均值
    g_slave_ctx.input_regs[4] = g_slave_ctx.temp_max;// 温度最大值
    g_slave_ctx.input_regs[5] = g_slave_ctx.humi_max;// 湿度最大值
    g_slave_ctx.input_regs[6] = g_slave_ctx.sample_cnt; // 采样次数
    g_slave_ctx.input_regs[7] = 0x0103;              // 固件版本 V1.03

    // 报警状态判断（基于模板配置的阈值）
    uint16_t temp_high = g_slave_ctx.hold_regs[2 - g_slave_ctx.template.data_config.hold_reg_start];
    uint16_t temp_low = g_slave_ctx.hold_regs[3 - g_slave_ctx.template.data_config.hold_reg_start];
    uint16_t humi_high = g_slave_ctx.hold_regs[4 - g_slave_ctx.template.data_config.hold_reg_start];
    uint16_t humi_low = g_slave_ctx.hold_regs[5 - g_slave_ctx.template.data_config.hold_reg_start];
    uint16_t alarm_en = g_slave_ctx.hold_regs[8 - g_slave_ctx.template.data_config.hold_reg_start];

    if (alarm_en) {
        g_slave_ctx.discrete_inputs[1] = (temp > temp_high) ? 1 : 0; // 温度上限报警
        g_slave_ctx.discrete_inputs[2] = (temp < temp_low) ? 1 : 0; // 温度下限报警
        g_slave_ctx.discrete_inputs[3] = (humi > humi_high) ? 1 : 0; // 湿度上限报警
        g_slave_ctx.discrete_inputs[4] = (humi < humi_low) ? 1 : 0; // 湿度下限报警
    } else {
        g_slave_ctx.discrete_inputs[1] = g_slave_ctx.discrete_inputs[2] = 0;
        g_slave_ctx.discrete_inputs[3] = g_slave_ctx.discrete_inputs[4] = 0;
    }

    pthread_mutex_unlock(&g_slave_ctx.data_mutex);
}

/**
 * @brief 处理 Modbus 请求（适配模板映射+自动寻址）
 */
static int modbus_slave_handle_request(uint8_t *req, int req_len) {
    if (!req || req_len <= 0) return -1;

    modbus_comm_param_t *comm_param = &g_slave_ctx.template.comm_param;
    modbus_data_config_t *data_cfg = &g_slave_ctx.template.data_config;

    // 地址过滤（仅响应当前地址或广播地址）
    uint8_t slave_addr = req[0];
    if (slave_addr != 0 && slave_addr != g_slave_ctx.current_addr) {
        return -1;
    }

    uint8_t func_code = req[1];
    uint8_t rsp[MODBUS_RTU_MAX_ADU_LENGTH] = {0};
    int rsp_len = 0;

    pthread_mutex_lock(&g_slave_ctx.data_mutex);

    switch (func_code) {
        // 0x01：读线圈
        case MODBUS_FC_READ_COILS: {
            uint16_t start = (req[2] << 8) | req[3];
            uint16_t cnt = (req[4] << 8) | req[5];
            if (start < data_cfg->coil_start || start + cnt > data_cfg->coil_start + data_cfg->coil_cnt || cnt == 0) {
                rsp[0] = slave_addr; rsp[1] = func_code | 0x80; rsp[2] = MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
                rsp_len = 3; break;
            }
            rsp[0] = slave_addr; rsp[1] = func_code; rsp[2] = (cnt + 7)/8;
            uint16_t idx = start - data_cfg->coil_start;
            for (int i = 0; i < cnt; i++) {
                if (g_slave_ctx.coils[idx + i]) rsp[3 + i/8] |= (1 << (i % 8));
            }
            rsp_len = 3 + rsp[2];
            break;
        }

            // 0x02：读离散量输入
        case MODBUS_FC_READ_DISCRETE_INPUTS: {
            uint16_t start = (req[2] << 8) | req[3];
            uint16_t cnt = (req[4] << 8) | req[5];
            if (start < data_cfg->discrete_input_start || start + cnt > data_cfg->discrete_input_start + data_cfg->discrete_input_cnt || cnt == 0) {
                rsp[0] = slave_addr; rsp[1] = func_code | 0x80; rsp[2] = MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
                rsp_len = 3; break;
            }
            rsp[0] = slave_addr; rsp[1] = func_code; rsp[2] = (cnt + 7)/8;
            uint16_t idx = start - data_cfg->discrete_input_start;
            for (int i = 0; i < cnt; i++) {
                if (g_slave_ctx.discrete_inputs[idx + i]) rsp[3 + i/8] |= (1 << (i % 8));
            }
            rsp_len = 3 + rsp[2];
            break;
        }

            // 0x03：读保持寄存器（主站扫描/心跳用）
        case MODBUS_FC_READ_HOLDING_REGISTERS: {
            uint16_t start = (req[2] << 8) | req[3];
            uint16_t cnt = (req[4] << 8) | req[5];
            if (start < data_cfg->hold_reg_start || start + cnt > data_cfg->hold_reg_start + data_cfg->hold_reg_cnt || cnt == 0) {
                rsp[0] = slave_addr; rsp[1] = func_code | 0x80; rsp[2] = MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
                rsp_len = 3; break;
            }
            rsp[0] = slave_addr; rsp[1] = func_code; rsp[2] = cnt * 2;
            uint16_t idx = start - data_cfg->hold_reg_start;
            for (int i = 0; i < cnt; i++) {
                rsp[3 + i*2] = (g_slave_ctx.hold_regs[idx + i] >> 8) & 0xFF;
                rsp[4 + i*2] = g_slave_ctx.hold_regs[idx + i] & 0xFF;
            }
            rsp_len = 3 + rsp[2];
            break;
        }

            // 0x04：读输入寄存器（温湿度数据采集）
        case MODBUS_FC_READ_INPUT_REGISTERS: {
            uint16_t start = (req[2] << 8) | req[3];
            uint16_t cnt = (req[4] << 8) | req[5];
            if (start < data_cfg->input_reg_start || start + cnt > data_cfg->input_reg_start + data_cfg->input_reg_cnt || cnt == 0) {
                rsp[0] = slave_addr; rsp[1] = func_code | 0x80; rsp[2] = MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
                rsp_len = 3; break;
            }
            rsp[0] = slave_addr; rsp[1] = func_code; rsp[2] = cnt * 2;
            uint16_t idx = start - data_cfg->input_reg_start;
            for (int i = 0; i < cnt; i++) {
                rsp[3 + i*2] = (g_slave_ctx.input_regs[idx + i] >> 8) & 0xFF;
                rsp[4 + i*2] = g_slave_ctx.input_regs[idx + i] & 0xFF;
            }
            rsp_len = 3 + rsp[2];
            break;
        }

            // 0x06：写单个寄存器（地址分配核心）
        case MODBUS_FC_WRITE_SINGLE_REGISTER: {
            uint16_t reg_addr = (req[2] << 8) | req[3];
            uint16_t reg_val = (req[4] << 8) | req[5];

            // 校验地址范围
            if (reg_addr < data_cfg->hold_reg_start || reg_addr >= data_cfg->hold_reg_start + data_cfg->hold_reg_cnt) {
                rsp[0] = slave_addr; rsp[1] = func_code | 0x80; rsp[2] = MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
                rsp_len = 3; break;
            }

            uint16_t idx = reg_addr - data_cfg->hold_reg_start;
            // 写入地址寄存器：更新当前地址并持久化
            if (reg_addr == comm_param->addr_reg) {
                uint8_t new_addr = reg_val & 0xFF;
                if (new_addr >= 1 && new_addr <= 247) {
                    g_slave_ctx.hold_regs[idx] = reg_val;
                    g_slave_ctx.current_addr = new_addr;
                    eeprom_write_addr(new_addr); // 持久化到 EEPROM
                    printf("Slave: Address updated to %d (persisted to EEPROM)\n", new_addr);
                } else {
                    rsp[0] = slave_addr; rsp[1] = func_code | 0x80; rsp[2] = MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE;
                    rsp_len = 3; break;
                }
            } else if (reg_addr == 0x0003) { // 数据清零寄存器（模板映射）
                memset(g_slave_ctx.temp_history, 0, sizeof(g_slave_ctx.temp_history));
                memset(g_slave_ctx.humi_history, 0, sizeof(g_slave_ctx.humi_history));
                g_slave_ctx.sample_cnt = 0;
                g_slave_ctx.temp_max = -400;
                g_slave_ctx.temp_min = 1250;
                g_slave_ctx.humi_max = 0;
                g_slave_ctx.humi_min = 1000;
                g_slave_ctx.hold_regs[idx] = reg_val;
            } else {
                g_slave_ctx.hold_regs[idx] = reg_val;
            }

            // 响应回声
            rsp[0] = slave_addr; rsp[1] = func_code;
            rsp[2] = (reg_addr >> 8) & 0xFF; rsp[3] = reg_addr & 0xFF;
            rsp[4] = (reg_val >> 8) & 0xFF; rsp[5] = reg_val & 0xFF;
            rsp_len = 6;
            break;
        }

            // 0x0F：写多个线圈
        case MODBUS_FC_WRITE_MULTIPLE_COILS: {
            uint16_t start = (req[2] << 8) | req[3];
            uint16_t cnt = (req[4] << 8) | req[5];
            uint8_t data_len = req[6];
            if (start < data_cfg->coil_start || start + cnt > data_cfg->coil_start + data_cfg->coil_cnt || cnt == 0 || data_len != (cnt +7)/8) {
                rsp[0] = slave_addr; rsp[1] = func_code | 0x80; rsp[2] = MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
                rsp_len = 3; break;
            }
            uint16_t idx = start - data_cfg->coil_start;
            memset(&g_slave_ctx.coils[idx], 0, cnt);
            for (int i = 0; i < cnt; i++) {
                if (req[7 + i/8] & (1 << (i % 8))) g_slave_ctx.coils[idx + i] = 1;
            }
            // 报警复位线圈（模板映射 0x0001）
            if (start <= 0x0001 && start + cnt > 0x0001) {
                g_slave_ctx.discrete_inputs[1] = g_slave_ctx.discrete_inputs[2] = 0;
                g_slave_ctx.discrete_inputs[3] = g_slave_ctx.discrete_inputs[4] = 0;
            }
            rsp[0] = slave_addr; rsp[1] = func_code;
            rsp[2] = (start >> 8) & 0xFF; rsp[3] = start & 0xFF;
            rsp[4] = (cnt >> 8) & 0xFF; rsp[5] = cnt & 0xFF;
            rsp_len = 6;
            break;
        }

            // 不支持的功能码
        default:
            rsp[0] = slave_addr; rsp[1] = func_code | 0x80; rsp[2] = MODBUS_EXCEPTION_ILLEGAL_FUNCTION;
            rsp_len = 3;
            break;
    }

    pthread_mutex_unlock(&g_slave_ctx.data_mutex);

    // 发送响应
    if (rsp_len > 0) {
        pthread_mutex_lock(&g_slave_ctx.ctx_mutex);
        int ret = modbus_send_raw(g_slave_ctx.ctx, rsp, rsp_len);
        pthread_mutex_unlock(&g_slave_ctx.ctx_mutex);
        if (ret != rsp_len) {
            printf("Slave: Send response failed, func=%02X, ret=%d\n", func_code, ret);
            return -1;
        }
    }

    return 0;
}

/**
 * @brief 接收处理线程（持续监听主站请求）
 */
static void *modbus_slave_recv_thread(void *arg) {
    uint8_t req_buf[MODBUS_RTU_MAX_ADU_LENGTH] = {0};
    modbus_mbap_t mbap;

    while (g_slave_ctx.is_running) {
        pthread_mutex_lock(&g_slave_ctx.ctx_mutex);
        int req_len = modbus_receive_raw(g_slave_ctx.ctx, &mbap, req_buf, sizeof(req_buf));
        pthread_mutex_unlock(&g_slave_ctx.ctx_mutex);

        if (req_len > 0) {
            modbus_slave_handle_request(req_buf, req_len);
        } else if (req_len != -1 && errno != EAGAIN) {
            printf("Slave: Receive failed, err=%s\n", strerror(errno));
            usleep(100 * 1000);
        }

        usleep(10 * 1000); // 降低 CPU 占用
    }

    printf("Slave: Recv thread exited\n");
    return NULL;
}

/**
 * @brief 数据更新线程（采样+状态维护）
 */
static void *modbus_slave_data_update_thread(void *arg) {
    srand(time(NULL)); // 随机数种子初始化

    while (g_slave_ctx.is_running) {
        // 采样使能判断（模板线圈 0x0000）
        pthread_mutex_lock(&g_slave_ctx.data_mutex);
        uint8_t sample_en = g_slave_ctx.coils[0];
        pthread_mutex_unlock(&g_slave_ctx.data_mutex);

        if (sample_en) {
            temp_humi_sample(); // 采样温湿度数据
        }

        // 采样频率控制（模板保持寄存器 0x0006）
        pthread_mutex_lock(&g_slave_ctx.data_mutex);
        uint16_t sample_freq = g_slave_ctx.hold_regs[6 - g_slave_ctx.template.data_config.hold_reg_start];
        pthread_mutex_unlock(&g_slave_ctx.data_mutex);
        sleep(1 / (sample_freq > 0 ? sample_freq : 1)); // 默认为 1Hz
    }

    printf("Slave: Data update thread exited\n");
    return NULL;
}

/**
 * @brief 初始化从站（模板加载+EEPROM地址读取+串口初始化）
 */
int modbus_slave_init(void) {
    memset(&g_slave_ctx, 0, sizeof(modbus_slave_ctx_t));
    g_slave_ctx.is_running = 0;

    // 初始化互斥锁
    if (pthread_mutex_init(&g_slave_ctx.ctx_mutex, NULL) != 0 ||
        pthread_mutex_init(&g_slave_ctx.data_mutex, NULL) != 0) {
        printf("Slave: Mutex init failed\n");
        return -1;
    }

    // 第一步：解析设备模板
    modbus_device_template_t template;
    if (modbus_template_parse(&template) != 0) {
        pthread_mutex_destroy(&g_slave_ctx.ctx_mutex);
        pthread_mutex_destroy(&g_slave_ctx.data_mutex);
        return -1;
    }
    g_slave_ctx.template = template;

    // 第二步：读取 EEPROM 中的地址（优先于模板默认地址）
    uint8_t eeprom_addr = eeprom_read_addr();
    g_slave_ctx.current_addr = (eeprom_addr >= 1 && eeprom_addr <= 247) ? eeprom_addr : template.comm_param.default_addr;
    printf("Slave: Load address: %d (from %s)\n", g_slave_ctx.current_addr,
           (eeprom_addr >= 1 && eeprom_addr <= 247) ? "EEPROM" : "template");

    // 第三步：配置串口
    int serial_fd = rtu_serial_config(&template.comm_param);
    if (serial_fd < 0) {
        pthread_mutex_destroy(&g_slave_ctx.ctx_mutex);
        pthread_mutex_destroy(&g_slave_ctx.data_mutex);
        return -1;
    }

    // 第四步：创建 Modbus 上下文
    g_slave_ctx.ctx = modbus_new_rtu_from_fd(serial_fd);
    if (!g_slave_ctx.ctx) {
        printf("Slave: Create modbus ctx failed\n");
        close(serial_fd);
        pthread_mutex_destroy(&g_slave_ctx.ctx_mutex);
        pthread_mutex_destroy(&g_slave_ctx.data_mutex);
        return -1;
    }

    // 配置从站地址和超时
    modbus_set_slave(g_slave_ctx.ctx, g_slave_ctx.current_addr);
    modbus_set_response_timeout(g_slave_ctx.ctx, 0, RESPONSE_TIMEOUT_MS * 1000);

    // 第五步：初始化数据区
    if (modbus_slave_init_data(&template) != 0) {
        modbus_free(g_slave_ctx.ctx);
        pthread_mutex_destroy(&g_slave_ctx.ctx_mutex);
        pthread_mutex_destroy(&g_slave_ctx.data_mutex);
        return -1;
    }

    g_slave_ctx.is_running = 1;
    printf("Slave: Init success. Device model: %s\n", template.dev_model);
    return 0;
}

/**
 * @brief 启动从站（启动所有线程）
 */
int modbus_slave_start(void) {
    if (!g_slave_ctx.is_running || !g_slave_ctx.ctx) return -1;

    // 创建接收线程
    if (pthread_create(&g_slave_ctx.recv_thread, NULL, modbus_slave_recv_thread, NULL) != 0) {
        printf("Slave: Create recv thread failed\n");
        return -1;
    }

    // 创建数据更新线程
    if (pthread_create(&g_slave_ctx.data_update_thread, NULL, modbus_slave_data_update_thread, NULL) != 0) {
        printf("Slave: Create data update thread failed\n");
        pthread_cancel(g_slave_ctx.recv_thread);
        return -1;
    }

    printf("Slave: Started. Listening on %s (addr=%d, baudrate=%d)\n",
           g_slave_ctx.template.comm_param.serial_dev, g_slave_ctx.current_addr,
           g_slave_ctx.template.comm_param.baudrate);
    return 0;
}

/**
 * @brief 停止从站
 */
int modbus_slave_stop(void) {
    g_slave_ctx.is_running = 0;

    pthread_join(g_slave_ctx.recv_thread, NULL);
    pthread_join(g_slave_ctx.data_update_thread, NULL);

    printf("Slave: Stopped\n");
    return 0;
}

/**
 * @brief 销毁从站（释放资源）
 */
int modbus_slave_deinit(void) {
    modbus_slave_stop();

    // 释放数据区内存
    pthread_mutex_lock(&g_slave_ctx.data_mutex);
    if (g_slave_ctx.coils) free(g_slave_ctx.coils);
    if (g_slave_ctx.discrete_inputs) free(g_slave_ctx.discrete_inputs);
    if (g_slave_ctx.hold_regs) free(g_slave_ctx.hold_regs);
    if (g_slave_ctx.input_regs) free(g_slave_ctx.input_regs);
    pthread_mutex_unlock(&g_slave_ctx.data_mutex);

    // 释放 Modbus 上下文和锁
    if (g_slave_ctx.ctx) modbus_free(g_slave_ctx.ctx);
    pthread_mutex_destroy(&g_slave_ctx.ctx_mutex);
    pthread_mutex_destroy(&g_slave_ctx.data_mutex);

    memset(&g_slave_ctx, 0, sizeof(modbus_slave_ctx_t));
    printf("Slave: Deinit success\n");
    return 0;
}

/**
 * @brief 从 EEPROM 读取地址（适配硬件，此处为模拟实现）
 * 实际场景需替换为硬件 EEPROM 驱动（如 I2C EEPROM：AT24C02）
 */
uint8_t eeprom_read_addr(void) {
    // 模拟读取：若文件存在则读取，否则返回 0（使用模板默认地址）
    FILE *fp = fopen("/tmp/slave_addr.bin", "rb");
    if (!fp) return 0;
    uint8_t addr = 0;
    fread(&addr, 1, 1, fp);
    fclose(fp);
    return addr;
}

/**
 * @brief 向 EEPROM 写入地址（模拟实现）
 */
int eeprom_write_addr(uint8_t addr) {
    FILE *fp = fopen("/tmp/slave_addr.bin", "wb");
    if (!fp) {
        printf("Slave: Write EEPROM failed\n");
        return -1;
    }
    fwrite(&addr, 1, 1, fp);
    fclose(fp);
    return 0;
}
